/**
 * ReportGear(2011)
 */
package com.reportgear.report.model.cell.style.format;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 
 * 格式化器工厂
 * 
 * @version 1.0 2011-3-10
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since Report 1.0
 */
public enum FormatterFactory {
	INSTANCE;

	FormatterFactory() {
		this.formats = new HashMap<String, CellFormatter>();
		this.keyMaps = new HashMap<Integer, List<FormatterKey>>();
		this.keyTypes = new HashMap<String, Integer>();
		this.captions = new ArrayList<String>();

		this.initCaptionsInfo();
		this.registerCellFormatters();
	}

	/**
	 * 常规
	 */
	public final static int TYPE_CUSTOM = 0;
	/**
	 * 数字
	 */
	public final static int TYPE_NUMBER = 1;

	/**
	 * 注册格式化器
	 */
	private void registerCellFormatters() {
		this.registerCellFormat(TYPE_NUMBER, "1234", new CellFormatter.IntegerFormatter("%d"));
		this.registerCellFormat(TYPE_NUMBER, "1234.5", new CellFormatter.FloatFormatter("%.1f"));
		this.registerCellFormat(TYPE_NUMBER, "1234.56", new CellFormatter.FloatFormatter("%.2f"));
		this.registerCellFormat(TYPE_NUMBER, "1234.567", new CellFormatter.FloatFormatter("%.3f"));
		this.registerCellFormat(TYPE_NUMBER, "1234.5678", new CellFormatter.FloatFormatter("%.4f"));
		this.registerCellFormat(TYPE_NUMBER, "1,234", new CellFormatter.IntegerFormatter("%,d"));
		this.registerCellFormat(TYPE_NUMBER, "1,234.5", new CellFormatter.FloatFormatter("%,.1f"));
		this.registerCellFormat(TYPE_NUMBER, "1,234.56", new CellFormatter.FloatFormatter("%,.2f"));
		this.registerCellFormat(TYPE_NUMBER, "1,234.567", new CellFormatter.FloatFormatter("%,.3f"));
		this.registerCellFormat(TYPE_NUMBER, "1,234.5678", new CellFormatter.FloatFormatter("%,.4f"));
	}

	private void initCaptionsInfo() {
		this.captions.add("常规");
		this.captions.add("数字");
		this.captions.add("货币");
		this.captions.add("百分比");
		this.captions.add("科学计数");
		this.captions.add("日期型");
		this.captions.add("时间型");
		this.captions.add("文本型");
	}

	/**
	 * 格式化串字典
	 */
	private Map<String, CellFormatter> formats;

	/**
	 * 分类对象表
	 */
	private Map<Integer, List<FormatterKey>> keyMaps;
	/**
	 * key分类映射
	 */
	private Map<String, Integer> keyTypes;
	/**
	 * 标签列表
	 */
	private List<String> captions;

	/**
	 * 获取格式分类列表
	 * 
	 * @return 格式分类列表
	 */
	public List<String> getFormatTypes() {
		List<String> types = new ArrayList<String>();

		types.add("常规");
		types.add("数字");
		// sorts.add("货币");
		// sorts.add("百分比");
		// sorts.add("科学计数");
		// sorts.add("日期型");
		// sorts.add("时间型");
		types.add("文本型");

		return types;
	}

	/**
	 * 注册格式化器
	 * 
	 * @param valueKey
	 *            value键值
	 * @param formatter
	 *            格式化器
	 */
	public void registerCellFormat(int type, String key, CellFormatter formatter) {
		this.formats.put(key, formatter);
		this.getTypeFormatterList(type).add(new FormatterKey(type, key));
		this.keyTypes.put(key, type);
	}

	/**
	 * 获取指定类型Formatter列表
	 * 
	 * @param type
	 *            类型
	 * @return Formatter列表
	 */
	public List<FormatterKey> getTypeFormatterList(int type) {
		List<FormatterKey> list = this.keyMaps.get(type);

		if (list == null) {
			list = new ArrayList<FormatterKey>();
			this.keyMaps.put(type, list);
		}

		return list;
	}

	/**
	 * 通过Caption获取格式化器信息列表
	 * 
	 * @param caption
	 *            标签
	 * @return 格式化器列表
	 */
	public List<FormatterKey> getFormattersByCaption(String caption) {
		return this.getTypeFormatterList(this.captions.indexOf(caption));
	}

	/**
	 * 根据键值获取格式化器
	 * 
	 * @param key
	 *            键值
	 * @return 格式化器
	 */
	public CellFormatter getFormatterByKey(String key) {
		return this.formats.get(key);
	}

	public static class FormatterKey {
		/**
		 * 格式化器类型
		 */
		public final int type;
		/**
		 * 格式化器键值
		 */
		public final String key;

		private FormatterKey(int type, String key) {
			this.type = type;
			this.key = key;
		}

		@Override
		public String toString() {
			return this.key;
		}
	}

	/**
	 * 获取键值对应的Type
	 * 
	 * @param key
	 *            键值
	 * @return 对应的类型
	 */
	public int getKeyType(String key) {
		Integer type = this.keyTypes.get(key);

		return type == null ? 0 : type;
	}
}
